package com.live.stamp.web.user.service.impl;

import com.live.stamp.base.service.impl.BaseSupportServiceImpl;
import com.live.stamp.base.token.TokenUtil;
import com.live.stamp.base.token.UserModelUtil;
import com.live.stamp.base.utils.BaseUtils;
import com.live.stamp.base.utils.MD5;
import com.live.stamp.base.utils.UUIDUtils;
import com.live.stamp.base.utils.VerCodeUtils;
import com.live.stamp.global.commonenum.HandleTypeEnum;
import com.live.stamp.global.commonenum.ListTypeEnum;
import com.live.stamp.web.message.service.MessageService;
import com.live.stamp.web.sms.service.model.SmsModel;
import com.live.stamp.web.user.baseDataService.UserBaseService;
import com.live.stamp.web.user.model.TUser;
import com.live.stamp.web.user.model.TUserAttention;
import com.live.stamp.web.user.model.TUserFriend;
import com.live.stamp.web.user.model.TUserShield;
import com.live.stamp.web.user.service.UserService;
import com.live.stamp.web.user.vo.TUserVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.container.core.common.BusinessException;
import org.springframework.boot.container.core.log.ZKLogger;
import org.springframework.boot.container.core.log.ZKLoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author cwd E-mail: wendong.cao@jsxfedu.com
 * @version 1
 * @date 2018/3/23 11:13
 */
@Service
public class UserServiceImpl extends BaseSupportServiceImpl implements UserService {
    private static final ZKLogger logger = ZKLoggerFactory.getLogger(UserServiceImpl.class);

    @Resource
    private UserBaseService userBaseService;

    @Resource
    private MessageService messageService;

    @Value("${sys.gfUserId}")
    private String gyUserId;

    @Override
    public String login(TUserVo tUserVo) throws BusinessException {
        logger.info("enter login method,  param tUserVo:{} ", tUserVo);

        TUser tUser = userBaseService.getUser(tUserVo);
        if(tUser == null) {
            throw new BusinessException("登录失败，用户名或手机号不存在！");
        }

        if(StringUtils.equals(MD5.md5Password(tUserVo.getPassword()), tUser.getPassword())){     //密码一致，登录成功
            return TokenUtil.buildToken(tUser.getId());
        } else {
            throw new BusinessException("登录失败，密码错误！");
        }
    }

    @Override
    public String register(TUserVo tUserVo) throws BusinessException {
        logger.info("enter register method,  param tUserVo:{} ", tUserVo);
        if(!VerCodeUtils.checkVerCode(tUserVo.getPhone(), tUserVo.getVerCode())) {
            throw new BusinessException("注册失败，验证码有误！");
        }

        TUserVo _tUserVo = new TUserVo();
        _tUserVo.setPhone(tUserVo.getPhone());
        _tUserVo.setState("1");
        if(userBaseService.getUser(_tUserVo) != null) {
            throw new BusinessException("注册失败，手机号已被占用！");
        }

        TUser tUser = new TUser();
        BaseUtils.copyProperties(tUser, tUserVo);
        tUser.setCreateTime(new Date());
        tUser.setId(UUIDUtils.getUUID());
        tUser.setSex("1");          //默认为男
        tUser.setState("1");
        tUser.setPassword(MD5.md5Password(tUserVo.getPassword()));

        userBaseService.addUser(tUser);

        TUserFriend tUserFriend = new TUserFriend();
        tUserFriend.setId(UUIDUtils.getUUID());
        tUserFriend.setFromUserId(tUser.getId());
        tUserFriend.setToUserId(gyUserId);
        tUserFriend.setTUserIdA(tUser.getId());
        tUserFriend.setTUserIdB(gyUserId);
        tUserFriend.setCreateTime(new Date());
        tUserFriend.setState("1");
        tUserFriend.setGreet(tUserVo.getGreet());

        TUserFriend _tUserFriend = new TUserFriend();
        BaseUtils.copyProperties(_tUserFriend, tUserFriend);
        _tUserFriend.setState("1");
        _tUserFriend.setId(UUIDUtils.getUUID());
        _tUserFriend.setTUserIdA(tUserFriend.getTUserIdB());
        _tUserFriend.setTUserIdB(tUserFriend.getTUserIdA());
        _tUserFriend.setCreateTime(new Date());
        userBaseService.addFriend(tUserFriend);
        userBaseService.addFriend(_tUserFriend);

        return TokenUtil.buildToken(tUser.getId());
    }

    @Override
    public String sendVerCode(SmsModel smsModel) throws BusinessException {
        logger.info("enter sendVerCode method,  param smsModel:{} ", smsModel);

        return VerCodeUtils.sendVerCode(smsModel);
    }

    @Override
    public String resetPassword(TUserVo tUserVo) throws BusinessException {
        logger.info("enter resetPassword method,  param tUserVo:{} ", tUserVo);
        if(!VerCodeUtils.checkVerCode(tUserVo.getPhone(), tUserVo.getVerCode())) {
            throw new BusinessException("重置密码失败，验证码有误！");
        }

        tUserVo.setState("1");
        TUser tUser = userBaseService.getUser(tUserVo);
        if(tUser == null) {
            throw new BusinessException("重置密码失败，无此用户！");
        }

        tUserVo.setId(tUser.getId());
        tUserVo.setPassword(MD5.md5Password(tUserVo.getPassword()));
        userBaseService.updateUser(tUserVo);

        return null;
    }

    @Override
    public int updateLookFriendTime(String userId) throws BusinessException {
        logger.info("enter updateLookFriendTime method,  param userId:{} ", userId);
        TUserVo tUserVo = new TUserVo();
        tUserVo.setId(userId);

        tUserVo.setLastLookFriendTime(new Date());

        return userBaseService.updateUser(tUserVo);
    }

    @Override
    public int updateLooAttenTime(String userId) throws BusinessException {
        logger.info("enter updateLooAttenTime method,  param userId:{} ", userId);

        TUserVo tUserVo = new TUserVo();
        tUserVo.setId(userId);

        tUserVo.setLastLookAttenTime(new Date());

        return userBaseService.updateUser(tUserVo);
    }

    @Override
    public TUserVo getUser(TUserVo tUserVo) throws BusinessException {
        logger.info("enter getUser method,  param tUserVo:{} ", tUserVo);

        TUser tUser = null;

        if(StringUtils.isBlank(tUserVo.getId())) {
            tUser = UserModelUtil.getUserModel();
        } else {
            tUser = userBaseService.getUser(tUserVo);
        }

        tUser.setFriendCount(getFriendCount(tUser));
        tUser.setAttentionCount(getAttionCount(tUser));

        BaseUtils.copyProperties(tUserVo, tUser);

        tUserVo.setIsFriend(isFriend(UserModelUtil.getUserModel().getId(), tUserVo.getId())?"1":"0");       //是否为好友
        tUserVo.setIsAttent(isAttent(UserModelUtil.getUserModel().getId(), tUserVo.getId())?"1":"0");       //是否已关注
        tUserVo.setIsShield(isShiled(UserModelUtil.getUserModel().getId(), tUserVo.getId())?"1":"0");       //是否已屏蔽

        return tUserVo;
    }

    @Override
    public List<TUserVo> amityList(TUserVo tUserVo) throws BusinessException {
        logger.info("enter amityList method,  param tUserVo:{} ", tUserVo);

        TUser tUser = UserModelUtil.getUserModel();
        if(tUser == null) {
            throw new BusinessException("获取列表失败，用户信息为空。");
        }

        String sql = "select u.*, r.createTime as reqTime, r.id as reqId, r.greet ";
        Map<String, Object> param = new HashMap<>();

        ListTypeEnum listTypeEnum = ListTypeEnum.valueOf(tUserVo.getListType());
        switch (listTypeEnum) {
            case FRIEND:            //好友
                if(!StringUtils.equals(tUserVo.getState(), "2")) {           //查询非好友申请列表
                    sql += " from t_user u, t_user_friend r where u.id=r.tUserIdB and u.state='1' and r.tUserIdA=:userId and r.state=:state ";
                    param.put("userId", tUser.getId());
                    param.put("state", tUserVo.getState());
                } else {
                    sql += " from t_user u, t_user_friend r where u.id=r.fromUserId and u.state='1' and r.toUserId=:userId and r.state='2' ";
                    param.put("userId", tUser.getId());
                }
                break;
            case ATTENT:            //关注
                sql += "  from t_user u, t_user_attention r where u.id=r.toUserId and u.state='1' and r.fromUserId=:userId order by r.createTime desc ";
                param.put("userId", tUser.getId());
                break;
            case FANS:             //粉丝
                sql += "  from t_user u, t_user_attention r where u.id=r.fromUserId and u.state='1' and r.toUserId=:userId order by r.createTime desc ";
                param.put("userId", tUser.getId());
                break;
        }

        try {
            return this.getDao().selectList(TUserVo.class, sql, param);
        } catch (SQLException e) {
            logger.error("获取好友列表失败，" + e);
            e.printStackTrace();

            throw new BusinessException("获取好友列表失败");
        }
    }

    @Override
    public List<TUser> queryUserList(TUserVo tUserVo) throws BusinessException {
        logger.info("enter queryUserList method,  param tUserVo:{} ", tUserVo);

        return userBaseService.queryUserList(tUserVo);
    }

    @Override
    public String  reqAddFriend(TUserVo tUserVo) throws BusinessException {
        logger.info("enter reqAddFriend method,  param tUserVo:{} ", tUserVo);

        TUser tUser = UserModelUtil.getUserModel();
        if(tUser == null) {
            throw new BusinessException("请求添加好友失败，用户信息为空。");
        }
        if(StringUtils.equals(tUser.getId(), tUserVo.getUserId())) {
            throw new BusinessException("请求添加好友失败，不能添加自己为好友！");
        }
        if(isSendAddFriend(tUser.getId(), tUserVo.getUserId())) {
            throw new BusinessException("请求添加好友失败，已有好友申请！");
        }
        if(isFriend(tUser.getId(), tUserVo.getUserId())) {
            throw new BusinessException("已为好友，不能重复添加好友！");
        }

        TUserFriend tUserFriend = new TUserFriend();
        tUserFriend.setId(UUIDUtils.getUUID());
        tUserFriend.setFromUserId(tUser.getId());
        tUserFriend.setToUserId(tUserVo.getUserId());
        tUserFriend.setTUserIdA(tUser.getId());
        tUserFriend.setTUserIdB(tUserVo.getUserId());
        tUserFriend.setCreateTime(new Date());
        tUserFriend.setState("2");
        tUserFriend.setGreet(tUserVo.getGreet());

        userBaseService.addFriend(tUserFriend);         //添加好友请求

        return null;
    }

    /**
     * 屏蔽用户
     * @param tUserVo
     * @return
     * @throws BusinessException
     */
    @Override
    public String shieldUser(TUserVo tUserVo) throws BusinessException {
        TUser tUser = UserModelUtil.getUserModel();
        if(tUser == null) {
            throw new BusinessException("屏蔽失败，用户信息为空。");
        }

//        tUserVo.setId(tUser.getId());
//        //将好友关系设置为屏蔽
//        userBaseService.shieldUserFriend(tUserVo);
//
//        tUserVo.setHandleType(HandleTypeEnum.QXGZ.toString());
//        this.handleAttention(tUserVo);          //取消关注
//
//        tUserVo.setId(tUserVo.getUserId());
//        tUserVo.setUserId(tUser.getId());
//        this.handleAttention(tUserVo);          //取消关注

        TUserShield tUserShield = new TUserShield();
        tUserShield.setId(UUIDUtils.getUUID());
        tUserShield.setFromUserId(tUser.getId());
        tUserShield.setToUserId(tUserVo.getUserId());
        tUserShield.setCreateTime(new Date());
        userBaseService.addShiled(tUserShield);

        return null;
    }

    @Override
    public String cancelShieldUser(TUserVo tUserVo) throws BusinessException {

        TUser tUser = UserModelUtil.getUserModel();
        if(tUser == null) {
            throw new BusinessException("取消屏蔽失败，用户信息为空。");
        }

        TUserShield tUserShield = new TUserShield();
        tUserShield.setFromUserId(tUser.getId());
        tUserShield.setToUserId(tUserVo.getUserId());
        userBaseService.deleteShiled(tUserShield);

        return null;
    }

    /**
     * 更新好友关系为黑名单
     * @param tUserVo
     * @throws BusinessException
     */
    public void updateFriendShield(TUserVo tUserVo) throws BusinessException {

    }

    @Override
    public String handleReqFriend(TUserVo tUserVo) throws BusinessException {
        logger.info("enter reqAddFriend method,  param tUserVo:{} ", tUserVo);
        TUser tUser = UserModelUtil.getUserModel();
        if(tUser == null) {
            throw new BusinessException("操作失败，用户信息为空。");
        }

        TUserFriend tUserFriend = userBaseService.getUserFriendById(tUserVo.getReqId());

        if(tUserFriend == null) {
            throw new BusinessException("操作失败，获取好友请求失败。");
        }

        if(StringUtils.equals(tUserVo.getHandleType(), HandleTypeEnum.TY.toString()) && isFriend(tUserFriend.getToUserId(), tUserFriend.getFromUserId())) {
            throw new BusinessException("添加失败，已为好友。");
        }

        HandleTypeEnum handleTypeEnum = HandleTypeEnum.valueOf(tUserVo.getHandleType());
        switch (handleTypeEnum) {
            case JJ:                //拒绝
                refusedReqFriend(tUserFriend);
                break;
            case TY:                //同意
                agreeReqFriend(tUserFriend);
                break;
        }

        return null;
    }

    @Override
    public String deleteFriend(TUserVo tUserVo) throws BusinessException {
        logger.info("enter deleteFriend method,  param tUserVo:{} ", tUserVo);
        TUser tUser = UserModelUtil.getUserModel();
        if(tUser == null) {
            throw new BusinessException("操作失败，用户信息为空。");
        }

        TUserFriend tUserFriend = new TUserFriend();
        tUserFriend.setTUserIdA(tUser.getId());
        tUserFriend.setTUserIdB(tUserVo.getUserId());

        userBaseService.deleteFriend(tUserFriend);
        return null;
    }

    @Override
    public String handleAttention(TUserVo tUserVo) throws BusinessException {
        logger.info("enter handleAttention method,  param tUserVo:{} ", tUserVo);
        TUser tUser = UserModelUtil.getUserModel();
        if(tUser == null) {
            throw new BusinessException("操作失败，用户信息为空。");
        }

        if(StringUtils.equals(tUser.getId(), tUserVo.getUserId())) {
            throw new BusinessException("操作失败，不能添加自己为关注！");
        }

        if(isAttent(tUser.getId(), tUserVo.getUserId()) && StringUtils.equals(HandleTypeEnum.GZ.toString(), tUserVo.getHandleType())) {
            throw new BusinessException("关注失败，已关注，不能重复关注！");
        }

        TUserAttention tUserAttention = new TUserAttention();
        tUserAttention.setFromUserId(tUser.getId());
        tUserAttention.setToUserId(tUserVo.getUserId());

        HandleTypeEnum handleTypeEnum = HandleTypeEnum.valueOf(tUserVo.getHandleType());
        switch (handleTypeEnum) {
            case GZ:                    //关注
                tUserAttention.setId(UUIDUtils.getUUID());
                tUserAttention.setCreateTime(new Date());
                userBaseService.addAttention(tUserAttention);

                messageService.sendAttenMessage(tUserVo);           //发送关注消息
                break;
            case QXGZ:                  //取消关注

                userBaseService.deleteAttention(tUserAttention);
                break;
        }

        return null;
    }

    @Override
    public String updateUserInfo(TUserVo tUserVo) throws BusinessException {
        logger.info("enter updateUserInfo method,  param tUserVo:{} ", tUserVo);
        TUser tUser = UserModelUtil.getUserModel();
        if(tUser == null) {
            throw new BusinessException("操作失败，用户信息为空。");
        }

        tUserVo.setId(tUser.getId());
        userBaseService.updateUser(tUserVo);
        return null;
    }

    /**
     * 是否已屏蔽
     * @param userAId
     * @param userBId
     * @return
     * @throws BusinessException
     */
    public boolean isShiled(String userAId, String userBId) throws BusinessException {
        logger.info("enter isShiled method,  param userAId:{}, userBId:{} ", userAId, userBId);

        TUserShield tUserShield = new TUserShield();
        tUserShield.setFromUserId(userAId);
        tUserShield.setToUserId(userBId);

        List<TUserShield> tUserShields = userBaseService.getShields(tUserShield);

        if(tUserShields!=null && tUserShields.size()>0) return true;
        else return false;
    }

    @Override
    public boolean isFriend(String userAId, String userBId) throws BusinessException {
        logger.info("enter isFirend method,  param userAId:{}, userBId:{} ", userAId, userBId);

        String sql = "select * from t_user_friend where tUserIdA=:tUserIdA and tUserIdB=:tUserIdB and state='1'";
        Map<String, Object> param = new HashMap<>();
        param.put("tUserIdA", userAId);
        param.put("tUserIdB", userBId);

        try {
            int count = this.getDao().count(sql, param);
            if(count>=1) {              //如果查询条数大于1说明为好友关系
                return true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            logger.error("查询是否为好友失败，" + e.getMessage());
            throw new BusinessException("查询是否为好友失败，" + e.getMessage());
        }

        return false;
    }

    /**
     * 是否已经有好友申请
     * @param userAId
     * @param userBId
     * @return
     * @throws BusinessException
     */
    public boolean isSendAddFriend(String userAId, String userBId) throws BusinessException {
        logger.info("enter isFirend method,  param userAId:{}, userBId:{} ", userAId, userBId);

        String sql = "select * from t_user_friend where ((tUserIdA=:tUserIdA and tUserIdB=:tUserIdB) or (tUserIdB=:tUserIdA and tUserIdA=:tUserIdB)) and state='2'";
        Map<String, Object> param = new HashMap<>();
        param.put("tUserIdA", userAId);
        param.put("tUserIdB", userBId);

        try {
            int count = this.getDao().count(sql, param);
            if(count>=1) {              //如果查询条数大于1说明为好友关系
                return true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            logger.error("查询是否为好友失败，" + e.getMessage());
            throw new BusinessException("查询是否为好友失败，" + e.getMessage());
        }

        return false;
    }

    @Override
    public boolean isAttent(String userAId, String userBId) throws BusinessException {
        logger.info("enter isAttent method,  param userAId:{}, userBId:{} ", userAId, userBId);

        String sql = "select * from t_user_attention where fromUserId=:fromUserId and toUserId=:toUserId";
        Map<String, Object> param = new HashMap<>();
        param.put("fromUserId", userAId);
        param.put("toUserId", userBId);

        try {
            int count = this.getDao().count(sql, param);
            if(count>=1) {              //如果查询条数大于1说明为好友关系
                return true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            logger.error("查询是否已关注失败，" + e.getMessage());
            throw new BusinessException("查询是否已关注失败，" + e.getMessage());
        }

        return false;
    }

    /**
     * 查询好友数量
     * @param tUser
     * @return
     */
    public int getFriendCount(TUser tUser) {
        String sql = "select * from t_user_friend where tUserIdA=:userId and state='1'";
        Map<String, Object> param = new HashMap<>();
        param.put("userId", tUser.getId());

        try {
            return this.getDao().count(sql, param);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new BusinessException("查询好友数量失败" + e.getMessage());
        }
    }

    /**
     * 查询被关注数量
     * @param tUser
     * @return
     */
    public int getAttionCount(TUser tUser) {
        String sql = "select * from t_user_attention where toUserId=:userId";
        Map<String, Object> param = new HashMap<>();
        param.put("userId", tUser.getId());

        try {
            return this.getDao().count(sql, param);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new BusinessException("查询关注数量失败" + e.getMessage());
        }
    }

    /**
     * 同意添加好友请求处理
     * @param tUserFriend
     */
    public void agreeReqFriend(TUserFriend tUserFriend) {
        logger.info("enter agreeReqFriend method,  param tUserVo:{} ", tUserFriend);
        tUserFriend.setState("1");      //已添加
        userBaseService.updateUserFriend(tUserFriend);

        TUserFriend _tUserFriend = new TUserFriend();
        BaseUtils.copyProperties(_tUserFriend, tUserFriend);
        _tUserFriend.setState("1");
        _tUserFriend.setId(UUIDUtils.getUUID());
        _tUserFriend.setTUserIdA(tUserFriend.getTUserIdB());
        _tUserFriend.setTUserIdB(tUserFriend.getTUserIdA());
        _tUserFriend.setCreateTime(new Date());
        userBaseService.addFriend(_tUserFriend);

    }

    /**
     * 拒绝添加好友请求处理
     * @param tUserFriend
     */
    public void refusedReqFriend(TUserFriend tUserFriend) {
        logger.info("enter refusedReqFriend method,  param tUserVo:{} ", tUserFriend);
        tUserFriend.setState("3");      //已拒绝
        userBaseService.updateUserFriend(tUserFriend);
    }
}
